﻿(*                  FnSharp              

   Base class library extensions and frameworks aimed 
   specifically at improving F# developers lives!

   Written by: Huw Simpson
   License: Microsoft Public License (Ms-PL) 
   Available at: http://fnsharp.codeplex.com

*)
namespace FnSharp.Bcl.Core

    open System
    open System.Threading

    //Adapted from http://fssnip.net/5V, ms-pl license.
    [<RequireQualifiedAccess>]
    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
    module LazyFuture =
        let ofAsync eager' (computation:Async<'a>) =
            let result = ref Unchecked.defaultof<_>
            let gate = new ManualResetEventSlim (false)
        
            let init =
                async { let! res = computation |> Async.Catch
                        result := res
                        gate.Set () }

            if eager' then init |> Async.Start

            lazy
                if not (eager') then init |> Async.Start
                gate.Wait ()
                match !result with
                | Choice1Of2 r -> r
                | Choice2Of2 e -> raise e

        let create eager' computation = ofAsync eager' (async { return computation () })
